package iterator;

/**
 * 迭代器
 */
interface Iterator_<T>{
    boolean hasNext();
    T next();
}

interface Collection_<T>{
    Collection_ add(T o);
    int getSize();
    Iterator_ iterator();
}

class Node{
    public Node next;
    private String name;
    public Node(String name){
        this.name = name;
    }

    @Override
    public String toString() {
        return name;
    }
}

class LinkLists implements Collection_<Node>{
    private Node head = null;
    private Node tail = null;
    private int size = 0;

    public LinkLists add(Node o){
        if(null == head){
            head = o;
            tail = o;
        }

        tail.next = o;
        tail = o;

        size++;

        return this;
    }

    public int getSize() {
        return size;
    }

    @Override
    public Iterator_ iterator() {
        return new LinkIterator();
    }
    // 这里为什么用个内部类 首先如果自己实现方法遍历是可以的， 但是如果定义了遍历接口方便对任何容器的约束。
    private class LinkIterator implements Iterator_<Node>{
        // 控制遍历游标
        private Node bl = head;

        @Override
        public boolean hasNext() {
            return null != bl;
        }

        @Override
        public Node next() {
            if(null != bl){
                Node o = bl;
                bl = bl.next;
                return o;
            }

            return null;
        }
    }
}

class ArrayLists implements Collection_<Object>{
    private int size = 0;
    private Object [] objects = new Object[10];

    public ArrayLists add(Object o){
        int len = objects.length;
        if(size < len){
            System.out.println("admin"+size);
        }else{
            // 扩容
            // create new array
            Object [] ny = new Object[len*2];

            System.arraycopy(objects, 0, ny, 0, len);

            objects = ny;

            System.out.println("k"+size);
        }

        objects[size] = o;
        size++;

        return this;
    }

    // 构造内部类进行遍历


    public int getSize() {
        return size;
    }

    @Override
    public Iterator_ iterator() {
        return new ArrayListIterator();
    }

    private class ArrayListIterator implements Iterator_<Object>{
        private int flg = 0;
        @Override
        public boolean hasNext() {
            return flg < size;
        }

        @Override
        public Object next() {
            return objects[flg++];
        }
    }
}

public class Iterator {
    public static void main(String[] args) {
        System.out.println("Iterator");

        Collection_ list = new ArrayLists();
        Collection_ lists = new LinkLists();

        for (int i = 0; i<30;i++){
            lists.add(new Node(i+""));
            list.add(new Object());
        }

        System.out.println(lists.getSize()+"----linklist");
        System.out.println(lists);


        System.out.println("===========iterator=============");
        Iterator_ ay = list.iterator();
        Iterator_ lkay = lists.iterator();
        System.out.println(ay);
        System.out.println(lkay);

        System.out.println("--------link list---------");
        while (lkay.hasNext()){
            System.out.println(lkay.next());
        }

        System.out.println("--------array list----------");
        while (ay.hasNext()){
            System.out.println(ay.next());
        }
    }
}
